package controller.login;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

import com.trek2000.android.enterprise.Enterprise;
import com.trek2000.android.enterprise.R;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;

import define.API;
import define.Key;
import model.login.CompaniesOfUserInfo;
import model.login.UserInfo;
import ui.activity.login.Login;
import utils.Utils;

/**
 * Created by trek2000 on 19/8/2014.
 */
public class LogInAsync extends AsyncTask<String, Void, Boolean> {

    /**
     * String section
     */

    private long user_global_id = 0;
    private long company_id = 0;
    private int company_id_group = 0;
    private long user_company_id = 0;

    private String ERROR = "";
    private String STATUS = "";


    private String USER_NAME = "";
    private String ACCOUNT_TYPE = "";
    private String TOKEN = "";
    private String ACCESS_TOKEN = "";
    /**
     * View section
     */

    /**
     * The others section
     */
    private Context mContext;
    private ArrayList <Long> mAlCompanyId = new ArrayList<>();

    public LogInAsync(Context context) {
        this.mContext = context;
    }

    @Override
    protected Boolean doInBackground(String... params) {
        return getData(params);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);

        // hide waiting dialog
        Utils.hideWaitingDialog();

        if (!result) {
            Toast.makeText(mContext.getApplicationContext(), ERROR ,
                    Toast.LENGTH_SHORT).show();
        } else {
            // go to Enterprise Activity
            ((Activity)mContext).finish();
            mContext.startActivity(new Intent(mContext, Enterprise.class));

        }
    }

    /**
     * Basic methods
     */
    private boolean getData(String[] params) {
        HttpPost mHttpPost = new HttpPost(API.LOGIN_CS_ENTERPRISE_APP);
        List<NameValuePair> mListValues = new ArrayList<NameValuePair>();
        /**
         * user_Name
         * password
         * device_token
         * device_OS
         */
        mListValues.add(new BasicNameValuePair(Key.USER_NAME, params[0]));
        if (!"".equals(Login.mSp.getString(Key.ACCESS_TOKEN, "")) ||
                Login.IS_LOGIN_BY_FACEBOOK ||
                Login.IS_LOGIN_BY_GOOGLE_PLUS)
            mListValues.add(new BasicNameValuePair(Key.ACCESS_TOKEN, params[1]));
        else
            mListValues.add(new BasicNameValuePair(Key.PASSWORD, params[1]));
        mListValues.add(new BasicNameValuePair(Key.DEVICE_TOKEN, params[2]));
        mListValues.add(new BasicNameValuePair(Key.DEVICE_OS, params[3]));

        try {
            mHttpPost.setEntity(new UrlEncodedFormEntity(mListValues));
            HttpParams mHttpParams = new BasicHttpParams();

            int TIMEOUT_CONNECTION = 30000;
            int TIMEOUT_SOCKET = 30000;

            HttpConnectionParams.setConnectionTimeout(
                    mHttpParams, TIMEOUT_CONNECTION);
            HttpConnectionParams.setSoTimeout(mHttpParams, TIMEOUT_SOCKET);
            HttpClient mHttpclient = new DefaultHttpClient(mHttpParams);
            HttpResponse mHttpResponse;
            mHttpResponse = mHttpclient.execute(mHttpPost);
            HttpEntity mHttpEntity = mHttpResponse.getEntity();
            String XML = EntityUtils.toString(mHttpEntity);

            Log.i("", LogInAsync.class.getSimpleName() + " " + XML);

            JSONObject mJoXml = new JSONObject(XML);
            //get string in mJoXml
            STATUS = mJoXml.getString(Key.STATUS);
            if (STATUS.equals(mContext.getString(R.string.success_))) {
                //get mJoUser in mJoXml
                JSONObject mJoUser = mJoXml.getJSONObject(Key.USER);
                //get string in mJoUser
                USER_NAME = mJoUser.getString(Key.USER_NAME);
                user_global_id = mJoUser.getLong(Key.USER_GLOBAL_ID);
                ACCOUNT_TYPE = mJoUser.getString(Key.ACCOUNT_TYPE);
                TOKEN = mJoUser.getString(Key.TOKEN);
                ACCESS_TOKEN = mJoUser.getString(Key.ACCESS_TOKEN);
                //get mJaCompanies in mJoUser
                JSONArray mJaCompanies = mJoUser.getJSONArray(Key.COMPANIES);
                ArrayList <CompaniesOfUserInfo> mAlCompanies = new ArrayList<>();
                if (!"[]".equals(mJaCompanies.toString())) {
                    //get mJoCompanies in mJaCompanies
                    for (int i = 0; i < mJaCompanies.length(); i++) {
                        JSONObject mJoCompanies = mJaCompanies.getJSONObject(i);
                        //get string in mJoCompanies
                        company_id = mJoCompanies.getLong(Key.COMPANY_ID);
                        company_id_group = mJoCompanies.getInt(Key.COMPANY_ID_GROUP);
                        user_company_id = mJoCompanies.getLong(Key.USER_COMPANY_ID);

                        CompaniesOfUserInfo companiesOfUserInfo = new CompaniesOfUserInfo(company_id, company_id_group, user_company_id);
                        if (!mAlCompanyId.contains(company_id)) {
                            mAlCompanies.add(companiesOfUserInfo);
                            mAlCompanyId.add(company_id);
                        }
                    }
                }
                //save data user when you was login to single ton to use
                UserInfo userInfo = new UserInfo(USER_NAME, user_global_id, ACCOUNT_TYPE,
                        TOKEN, ACCESS_TOKEN, mAlCompanies);
                Login.user.setUserInfo(userInfo);
                //save user login info to shared preferences for the next login
                Login.mSpEditor.putString(Key.USER_EMAIL, params[0]);
                Login.mSpEditor.putString(Key.USER_NAME, USER_NAME);
                Login.mSpEditor.putString(Key.PASSWORD, params[1]);
                Login.mSpEditor.putLong(Key.USER_GLOBAL_ID, user_global_id);
                Login.mSpEditor.putString(Key.ACCOUNT_TYPE, ACCOUNT_TYPE);
                Login.mSpEditor.putString(Key.TOKEN, TOKEN);
                Login.mSpEditor.putString(Key.ACCESS_TOKEN, ACCESS_TOKEN);
                Login.mSpEditor.commit();
                return  true;
            } else if (STATUS.equals(mContext.getString(R.string.error))) {
                ERROR = mJoXml.getString(Key.ERROR);
                return false;
            }

        } catch (ClassCastException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ConnectTimeoutException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
}